/*******************************************************************************

    copyright:  Copyright (c) 2007 Matthias Walter. All rights reserved

    license:    BSD style: $(LICENSE)

    version:    Initial release: May 2007

    author:     Matthias Walter

*******************************************************************************/

module fcgi.Connection;

private import  tango.io.device.Conduit;
private import  tango.stdc.stdlib;
private import  tango.stdc.string;

private import  fcgi.Base;

const int FastCGIListenSockFileNo = 0;

class FastCGIConnection
{
    private enum FastCGIConnectionState
    {
        isFastCGI,
        isCGIBeforeRequest,
        isCGIAfterRequest
    };

    private int fileDescriptor_;
    private char[] validAddresses_;
    private FastCGIConnectionState state_;

    public this (int fileDescriptor = FastCGIListenSockFileNo)
    {
        OS_LibInit (null);

        fileDescriptor_ = fileDescriptor;
        char* p = getenv("FCGI_WEB_SERVER_ADDRS");
        validAddresses_ = p == null ? null : p[0 .. strlen(p)+1].dup;

        state_ = OS_IsFcgi (fileDescriptor) == 0 ? FastCGIConnectionState.isCGIBeforeRequest : FastCGIConnectionState.isFastCGI;
    }

    public this (char[] host, char[] port, char[] validAddresses = null, int backlog = 10)
    {
        OS_LibInit (null);

        validAddresses_ = validAddresses == null ? null : validAddresses ~ '\0';

        char[] path = host ~ ":" ~ port ~ '\0';
        fileDescriptor_ = OS_CreateLocalIpcFd (path.ptr, backlog);

        state_ = FastCGIConnectionState.isFastCGI;
    }

    public bool isCGI ()
    {
        return state_ != FastCGIConnectionState.isFastCGI;
    }

    package int accept ()
    {
        if (state_ == FastCGIConnectionState.isFastCGI)
        {
            // FastCGI accept
            int result = OS_Accept (fileDescriptor_, false, validAddresses_.ptr);
            return result;
        }
        else if (state_ == FastCGIConnectionState.isCGIBeforeRequest)
        {
            // first CGI accept
            state_ = FastCGIConnectionState.isCGIAfterRequest;
            return fileDescriptor_;
        }
        else
        {
            // later CGI accept
            return -2;
        }
    }

}
